<template>
  <div class="apply-card">
    <h1 style="font-size: 23px;">申请开店</h1>
    <!-- 分割线 -->
    <el-divider></el-divider>
    <el-form v-loading="loading" ref="applyStoreFormRef" :model="form" label-width="120px" :rules="rules" status-icon>
      <!-- 店铺名 -->
      <el-form-item prop="storeName" label="店铺名称">
        <el-input input-style="text-align: center;" style="width: 83%;" v-model="form.storeName" />
      </el-form-item>
      <!-- 身份证号 -->
      <el-form-item prop="idCardNumber" label="本人身份证号">
        <el-input input-style="text-align: center;" style="width: 83%;" v-model="form.idCardNumber" />
      </el-form-item>
      <!-- 注册资金 -->
      <el-form-item prop="registeredCapital" label="注册资金">
        <!-- 利用element-plus自带的数字输入 -->
        <el-input-number :precision="2" :controls="false" style="width: 83%;" v-model="form.registeredCapital"
          :max="10000000.00" />
      </el-form-item>
      <!-- 备案地址 -->
      <el-form-item prop="filingAddress" label="备案地址">
        <el-input input-style="text-align: center;" style="width: 83%;" v-model="form.filingAddress" />
      </el-form-item>
      <!-- 商店销售类别 -->
      <el-form-item prop="category" label="所售商品类型" class="category" style="width: 85%;">
        <!-- 动态标签 -->
        <el-tag class="tag" v-for="tag in form.category" :key="tag" closable :disable-transitions="false"
          @close="handleClose(tag)">
          {{ tag }}
        </el-tag>
        <el-input v-if="inputVisible" ref="InputRef" v-model="inputValue" @keyup.enter="handleInputConfirm"
          @blur="handleInputConfirm" />
        <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput">
          + New Tag
        </el-button>
      </el-form-item>
      <!-- 商店图片 -->
      <el-form-item prop="pictures" label="商店图片">
        <h1 class="upload-tip">
          <el-icon style="margin-right: 5px; font-size: 12px;">
            <Warning />
          </el-icon>
          注意：请上传1张商店缩略图，1~5张店内的轮播图。至少需要1张缩略图，1张轮播图。
        </h1>
        <el-upload class="upload-board" v-model:file-list="fileList" action="#" multiple list-type="picture-card"
          :on-preview="handlePictureCardPreview" :on-remove="handleRemove" ref="upload" :on-change="handleChange"
          :limit="fileNumLimit" :on-exceed="handleExceed" :before-upload="beforeUpload" :auto-upload="false"
          :headers="headers">
          <el-icon>
            <Plus />
          </el-icon>
          <template #tip>
            <div style="font-size: 12px; margin-top:10px;">
              <el-icon style="margin-right: 5px;">
                <InfoFilled />
              </el-icon>
              确保图片顺序：第一张图为400×400的缩略图，第二张及往后的为1800×600轮播图
            </div>
          </template>
        </el-upload>

      </el-form-item>
      <!-- 商店简介 -->
      <el-form-item prop="storeProfile" label="商店简介">
        <el-input style="width: 83%;" v-model="form.storeProfile" type="textarea" />
      </el-form-item>
      <p style="display: flex; justify-content: center;">
        <el-button type="primary" @click="onSubmit">发起申请</el-button>
        <el-button @click="resetForm(applyStoreFormRef)">重置表单</el-button>
      </p>
    </el-form>
  </div>

  <!-- 模态框查看图片 -->
  <el-dialog v-model="dialogVisible">
    <img :src="dialogImageUrl" alt="Preview Image" class="preview-img" />
  </el-dialog>
</template>


<script setup>
import { onMounted, reactive, ref, nextTick, getCurrentInstance } from 'vue'
import { useStore } from 'vuex'
import { idCardNumber, registeredCapital, category } from '../../../../validator';

const store = useStore()

// do not use same name with ref
let form = reactive({
  initiateTime: '',
  processTime: '',
  storeName: '',
  idCardNumber: '',
  userId: '',
  registeredCapital: 1000.0,
  storeProfile: '',
  filingAddress: '',
  pictures: ['https://unsplash.it/400/400?random'],
  category: [],
  status: 0,  // 申请中，尚未开业
});

onMounted(() => {
  form.userId = store.state.user.userId;
})

const inputValue = ref('')
const inputVisible = ref(false)
const InputRef = ref()
const applyStoreFormRef = ref()
const { proxy } = getCurrentInstance();
let loading = ref(false);

let dialogVisible = ref(false);
const dialogImageUrl = ref('')
// 上传后的文件列表
let fileList = ref([])
// 允许的文件类型
let fileType = ["png", "jpg", "bmp", "jpeg", "gif", "webp"];
// 上传文件大小限制，单位MB
let fileSizeLimit = 10;
// 附件数量限制
let fileNumLimit = 6;
// 请求头
let headers = { "Content-Type": "multipart/form-data" };

// 上传文件之前
const beforeUpload = (file) => {
  console.log('beforeUpload: ', file);
  if (file.type !== "" || file.type != null || file.type !== undefined) {
    // 截取文件的后缀，判断文件类型
    const FileExt = file.name.replace(/.+\./, "").toLowerCase();
    // 计算文件大小是否符合限制
    const isSizeAvail = (file.size / 1024 / 1024) < fileSizeLimit;
    // 如果大小超过限制
    if (!isSizeAvail) {
      this.$showMessage(`上传文件大小不能超过 ${fileSizeLimit}MB!`);
      return false;
    }
    // 如果文件类型不在允许上传的范围内
    if (fileType.includes(FileExt)) {
      return true;
    } else {
      ElMessage.error("上传文件格式不正确!");
      return false;
    }
  }
}

// 超出文件个数的回调
const handleExceed = () => {
  ElMessage({
    showClose: true,
    type: 'warning',
    message: `超出最大上传文件数量${fileNumLimit}的限制！`
  });
}

// 处理移除文件
const handleRemove = (uploadFile, uploadFiles) => {
  fileList.value = uploadFiles;
}

// 处理文件变动
const handleChange = (uploadFile, uploadFiles) => {
  fileList.value = uploadFiles;
}

// 处理Preview
const handlePictureCardPreview = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url
  dialogVisible.value = true
}

// 上传图片的方法
const uploadFile = async () => {
  if (fileList.value.length < 2) {
    ElMessage.warning("请至少上传2张图片！");
    return Promise.reject("too few pictures");
  } else {
    let formData = new FormData();  // 将文件封装进FormData
    fileList.value.forEach(file => {
      formData.append('files', file.raw)
    })
    // 调用上传接口
    let fileNames = await proxy.$api.img.uploadImg(formData);
    form.pictures = fileNames.data;
    return "ok";
  }
}

// 表单的校验规则
const rules = reactive({
  storeName: [
    { required: true, message: '请输入店铺名', trigger: 'blur' },
    { min: 1, max: 12, message: '长度应该在1~12个字符之间', trigger: 'blur' },
  ],
  idCardNumber: [
    { required: true, message: '请输入身份证号码', trigger: 'blur' },
    {
      validator: idCardNumber, trigger: 'blur'
    },
  ],
  registeredCapital: [
    { required: true, message: '请输入注册资金', trigger: 'blur' },
    {
      validator: registeredCapital, trigger: 'blur',
    },
  ],
  category: [
    { required: true, message: '至少输入一种商品类型（商店标签）', trigger: 'blur' },
    {
      type: 'array',
      defaultField: {
        validator: category, trigger: 'blur'
      }
    }
  ],
  filingAddress: [
    { required: true, message: '请输入备案地址', trigger: 'blur' },
    { min: 1, max: 32, message: '长度应该在1~32个字符之间', trigger: 'blur' },
  ],
  storeProfile: [
    { required: true, message: '请输入商店简介', trigger: 'blur' },
    { min: 1, max: 128, message: '长度应该在1~128个字符之间', trigger: 'blur' },
  ],
})

// 提交表单
const onSubmit = async () => {
  let valid = await applyStoreFormRef.value.validate();
  if (valid) {
    loading.value = true;
    // 调用图片上传并更新pictures
    let uploadRet = await uploadFile().catch(error => {
      console.log(error);
      ElMessage.error({ showClose: true, message: "图片上传失败" });
      loading.value = false;
    });
    if (uploadRet === "ok") {
      let res = await proxy.$api.store.storeOpenRequest(form).catch(error => {
        console.log(error);
        ElMessage.error({ showClose: true, message: "发起开店申请失败" });
        loading.value = false;
      });
      if (res.status === 200) {
        ElMessage.success({ showClose: true, message: '发起申请成功' });
      }
    }
    loading.value = false;
  } else {
    console.log('表单信息不合法')
  }
}

// 重置表单
const resetForm = (formEl) => {
  if (!formEl) return
  formEl.resetFields();
  // fileList.
}

// 删除标签
const handleClose = (tag) => {
  form.category.splice(form.category.indexOf(tag), 1)
}

// 展示输入框
const showInput = () => {
  inputVisible.value = true
  nextTick(() => {
    if (InputRef !== null)
      InputRef.value.input.focus()
  })
}

// 添加标签
const handleInputConfirm = () => {
  if (inputValue.value) {
    form.category.push(inputValue.value);
  }
  inputVisible.value = false
  inputValue.value = ''
}
</script>


<style lang="less" scoped>
.apply-card {
  background: linear-gradient(180deg, #ecf0f5ee 0%, #ffffffea 100%);
  padding: 30px;
  border-radius: 10px;

  /* 分割线 */

  .el-divider {
    border-top: 2px solid rgba(170, 165, 165, 0.651);
  }

  .el-form {

    .category {
      .tag {
        margin-right: 8px;
        margin-top: 4px;
        margin-bottom: 4px;
      }

      .el-input {
        width: 80px;
      }

      .el-button {
        margin-top: 4px;
        margin-bottom: 4px;
      }
    }
  }
}

.preview-img {
  width: 100%;
  border-radius: 10px;
  object-fit: cover;
}
</style>